package com.kuang.handler.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.kuang.vo.AuthResponse;
import com.kuang.vo.ResponseCode;
import com.kuang.vo.UserVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2021/8/3 14:36
 */
@Service
public class JwtService {

    private static final Logger log = LoggerFactory.getLogger(JwtService.class);


    // 1:定义加密的盐信息 enc
    private static final String KEY = "www.kuangstudy.com.1123.";
    // 2:发行者
    private static final String ISSUSER = "YYKK";
    // 3:定义token的过期时间
    //private static final Long TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24 * 30L;
    public static final Long TOKEN_EXPIRE_TIME = 1000 * 10L;

    // 1 :header --确定算法和类型
    // 2 :payload --确定要加密的数据
    // 3 :sign --把header和payload + 盐 进行同一组合生成一个token
    // 有状态：服务端来维护你的数据信息，消耗的服务器资源
    // 无状态：服务段不维护你数据信息，不会消耗服务器资源
    public String token(UserVo userVo) {
        // token签发的时间
        Date now = new Date();
        // 1：确定加密算法 -- header + 盐
        Algorithm algorithm = Algorithm.HMAC256(KEY);
        // 2: 开始创建和生成token token1 == token2
        String token = JWT.create()
                .withIssuer(ISSUSER) // 签发者
                .withIssuedAt(now)// token签发的时间
                .withExpiresAt(new Date(now.getTime() + TOKEN_EXPIRE_TIME)) // 设定jwt的服务器过期时间
                .withClaim("username", userVo.getUsername())
                .withClaim("userid", userVo.getUserid())
                .withClaim("openid", userVo.getOpenid())
                .sign(algorithm);
        return token;
    }


    /**
     * 验证token
     *
     * @param token
     * @param username
     * @return
     */
    public AuthResponse verify(String token, String username) {
        log.info("verifying jwt - username = {}", username);
        try {
            // 1: 定义算法
            Algorithm algorithm = Algorithm.HMAC256(KEY);
            // 2: 进行校验
            JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer(ISSUSER)
                    .withClaim("username", username).build();
            jwtVerifier.verify(token);// 如果校验成功，不做任何动作 ，如果校验失败就抛出异常
            return AuthResponse.code(ResponseCode.SUCCESS);
        } catch (Exception ex) {
            log.error("auth verify fail,{}", ex);
            return AuthResponse.code(ResponseCode.USER_NOT_FOUND);
        }
    }

    /**
     * 验证token
     *
     * @param token
     * @param userid
     * @return
     */
    public AuthResponse verifyUserId(String token, String userid) {
        log.info("verifying jwt - userid = {}", userid);
        try {
            // 1: 定义算法
            Algorithm algorithm = Algorithm.HMAC256(KEY);
            // 2: 进行校验
            JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer(ISSUSER)
                    .withClaim("userid", userid).build();
            jwtVerifier.verify(token);
            return AuthResponse.code(ResponseCode.SUCCESS);
        } catch (Exception ex) {
            log.error("auth verify fail,{}", ex);
            return AuthResponse.code(ResponseCode.USER_NOT_FOUND);
        }
    }



    /**
     * 验证token
     *
     * @param token
     * @param openid
     * @return
     */
    public AuthResponse verifyOpenid(String token, String openid) {
        log.info("verifying jwt - openid = {}", openid);
        try {
            // 1: 定义算法
            Algorithm algorithm = Algorithm.HMAC256(KEY);
            // 2: 进行校验
            JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer(ISSUSER)
                    .withClaim("openid", openid).build();
            jwtVerifier.verify(token);
            return AuthResponse.code(ResponseCode.SUCCESS);
        } catch (Exception ex) {
            log.error("auth verify fail,{}", ex);
            return AuthResponse.code(ResponseCode.USER_NOT_FOUND);
        }
    }
}
